package com.easy.threads.actuator;


import com.easy.common.IWork;
import com.easy.config.log.MyLog;
import com.easy.threads.factory.ThreadFactory;
import com.easy.threads.singleton.Constant;
import com.easy.utils.JobPoolManage;
import com.easy.utils.PartitionJobStatus;

import java.util.logging.Level;

/**
 * 描述: 工作
 * 任务执行线程，如果没有可执行任务，线程等待执行，通过监听任务唤醒线程
 *
 * @author gwj
 * @date 2023年12月14日 9:57
 */

public class Job extends Thread {

    /**
     * 具体任务执行接口
     */
    private IWork work;
    /**
     * 线程是否重复执行
     */
    private boolean start = true;
    /**
     * 线程执行结束后是否等待唤醒，主要针对临时线程
     */
    private boolean wait = true;
    /**
     * 当前线程状态
     */
    private String jobStatus;
    /**
     * 当前线程标识，执行一次与执行后等待
     */
    private String threadFlag;

    private final String partition;

    public Job(String partition) {
        this.partition = partition;
    }

    @Override
    public void run() {
        MyLog.getLogger().log(Level.INFO,"THREAD START RUN ");
        while (isStart()) {

            if (getWork() != null) {
                //方法执行前
                getWork().doBefore();
                //执行方法
                getWork().execute();
                //方法执行后
                getWork().doAfter();

                //任务分区状态为立即停止
                boolean parStatus = PartitionJobStatus.STOP.equals(PartitionJobStatus.getStatusFlag(partition));
                //任务类型为只执行一次
                boolean threadLoopRunFlagExecuteOnceFlag = getThreadFlag().equals(Constant.THREAD_LOOP_RUN_FLAG_EXECUTE_ONCE);
                if (threadLoopRunFlagExecuteOnceFlag || parStatus) {
                    kill();
                    wait = false;
                }

                setWork(null);

            }

            if (wait) {
                if (getThreadFlag().equals(Constant.THREAD_LOOP_RUN_FLAG_TRUE)) {
                    setJobStatus(Constant.THREAD_STATUS_WAITING);
                    try {
                        synchronized (this) {
                            //添加任务到等待区
                            JobPoolManage.addWaitJob(partition,this);
                            this.wait();
                        }
                    } catch (InterruptedException e) {
                        MyLog.getLogger().log(Level.SEVERE,"wait error ",e.getMessage());
                    }
                }

            }

        }
        ThreadFactory.reduceTempJobCount();
    }

    private IWork getWork() {
        return work;
    }

    public void setWork(IWork work) {
        this.work = work;
    }


    public void jobNotify() {
        MyLog.getLogger().log(Level.INFO,"{},notify",this.getName());
        synchronized (this) {
            this.notify();
        }
        setJobStatus(Constant.THREAD_STATUS_RUN);
    }

    public void kill() {
        this.start = false;
    }

    private boolean isStart() {
        return start;
    }

    public String getThreadFlag() {
        return threadFlag == null ? Constant.THREAD_LOOP_RUN_FLAG_TRUE : threadFlag;
    }

    public void setThreadFlag(String threadFlag) {
        this.threadFlag = threadFlag;
    }

    public String getJobStatus() {
        return jobStatus;
    }

    public void setJobStatus(String jobStatus) {
        this.jobStatus = jobStatus;
    }

}
